<template>
  <el-dialog
    :title="script?.name"
    :model-value="modelValue"
    @update:model-value="(val) => emit('update:modelValue', val)"
    width="80%"
    top="10vh"
    :close-on-click-modal="false"
    class="script-editor-dialog"
    :destroy-on-close="true"
    align-center
    :modal-class="'centered-dialog'"
  >
    <div class="editor-container" v-loading="loading">
      <div class="editor-header">
        <div class="script-info">
          <div class="info-row">
            <div class="editable-tag" @click="handleVersionEdit">
              <el-tag size="small" v-if="!isVersionEditing">{{
                version || script?.version
              }}</el-tag>
              <el-input
                v-else
                v-model="version"
                size="small"
                class="tag-input"
                ref="versionInputRef"
                @blur="handleVersionBlur"
                @keyup.enter="handleVersionBlur"
                @keyup.esc="cancelVersionEdit"
                v-focus
              />
            </div>
            <el-tag size="small" type="info" v-if="script?.type">{{ script.type }}</el-tag>
            <div class="editable-tag" @click="handleAuthorEdit">
              <el-tag size="small" type="success" v-if="!isAuthorEditing">{{
                author || script?.author || '添加作者'
              }}</el-tag>
              <el-input
                v-else
                v-model="author"
                size="small"
                class="tag-input"
                ref="authorInputRef"
                @blur="handleAuthorBlur"
                @keyup.enter="handleAuthorBlur"
                @keyup.esc="cancelAuthorEdit"
                v-focus
              />
            </div>
            <span class="update-time">最后更新: {{ script?.latestUpdateTime }}</span>
          </div>
          <div class="info-row">
            <el-input
              v-model="description"
              placeholder="添加描述..."
              size="small"
              class="description-input"
              :class="{ 'no-border': !isDescriptionFocused }"
              clearable
              @focus="isDescriptionFocused = true"
              @blur="isDescriptionFocused = false"
            >
              <template #prefix>
                <el-icon><InfoFilled /></el-icon>
              </template>
            </el-input>
          </div>
        </div>
        <div class="header-right">
          <el-select v-model="language" size="small" class="language-select">
            <el-option label="Shell" value="shell" />
            <el-option label="Python" value="python" />
            <el-option label="JavaScript" value="javascript" />
            <el-option label="Bash" value="bash" />
          </el-select>
        </div>
      </div>
      <div class="editor-body">
        <monaco-editor v-model="content" :language="language" ref="editorRef" />
      </div>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="emit('update:modelValue', false)">取消</el-button>
        <el-button type="primary" @click="handleSave" :loading="saving">
          <el-icon><UploadFilled /></el-icon>保存
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { UploadFilled, InfoFilled } from '@element-plus/icons-vue'
import { taskService } from '@/api/taskService'
import type { Script } from '@/api/types'
import MonacoEditor from '@/components/common/MonacoEditor.vue'
import { decode as base64Decode, encode } from '@/utils/base64'

interface Props {
  modelValue: boolean
  script?: Script
}

interface Emits {
  (e: 'update:modelValue', value: boolean): void
  (e: 'success'): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const loading = ref(false)
const saving = ref(false)
const content = ref('')
const editorRef = ref()
const language = ref('shell')
const description = ref('')
const version = ref('')
const author = ref('')
const isDescriptionFocused = ref(false)
const isVersionEditing = ref(false)
const isAuthorEditing = ref(false)
const versionInputRef = ref()
const authorInputRef = ref()

// 自定义指令：自动聚焦
const vFocus = {
  mounted: (el: HTMLElement) => {
    el.querySelector('input')?.focus()
  },
}

// 监听对话框显示状态
watch(
  () => props.modelValue,
  (val) => {
    if (val && props.script) {
      loadScriptContent()
    }
  },
)

// 加载脚本内容
const loadScriptContent = async () => {
  if (!props.script) return
  loading.value = true
  try {
    const data = await taskService.getScriptById(props.script.id)
    content.value = data.content ? base64Decode(data.content) : ''
    description.value = data.description || ''
    version.value = data.version || ''
    author.value = data.author || ''
    // 根据文件扩展名设置语言
    const ext = props.script.name.split('.').pop()?.toLowerCase()
    switch (ext) {
      case 'py':
        language.value = 'python'
        break
      case 'js':
        language.value = 'javascript'
        break
      case 'sh':
      case 'bash':
        language.value = 'shell'
        break
      default:
        language.value = 'shell'
    }
  } catch (err) {
    console.error('加载脚本内容失败:', err)
    ElMessage.error('加载脚本内容失败')
    emit('update:modelValue', false)
  } finally {
    loading.value = false
  }
}

// 处理版本号编辑
const handleVersionEdit = () => {
  isVersionEditing.value = true
  version.value = version.value || props.script?.version || ''
}

// 处理版本号编辑完成
const handleVersionBlur = () => {
  if (!version.value.trim()) {
    version.value = props.script?.version || ''
  }
  isVersionEditing.value = false
}

// 取消版本号编辑
const cancelVersionEdit = () => {
  version.value = props.script?.version || ''
  isVersionEditing.value = false
}

// 处理作者编辑
const handleAuthorEdit = () => {
  isAuthorEditing.value = true
  author.value = author.value || props.script?.author || ''
}

// 处理作者编辑完成
const handleAuthorBlur = () => {
  isAuthorEditing.value = false
}

// 取消作者编辑
const cancelAuthorEdit = () => {
  author.value = props.script?.author || ''
  isAuthorEditing.value = false
}

// 保存脚本
const handleSave = async () => {
  if (!props.script) return
  saving.value = true
  try {
    loading.value = true
    const data = {
      id: props.script.id,
      name: props.script.name,
      content: content.value,
      version: version.value,
      author: author.value || 'admin',
      description: description.value || '这个人很懒,什么都没留下...',
    }

    await taskService.updateScript(data)

    ElMessage.success('保存成功')
    emit('success')
    emit('update:modelValue', false)
  } catch (err) {
    console.error('保存失败:', err)
    ElMessage.error('保存失败')
  } finally {
    saving.value = false
    loading.value = false
  }
}
</script>

<style scoped lang="scss">
.script-editor-dialog {
  :deep(.el-dialog__body) {
    padding: 0;
  }

  :deep(.el-dialog) {
    margin: 0 !important;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    max-height: 80vh;
    display: flex;
    flex-direction: column;
  }

  :deep(.el-dialog__body) {
    flex: 1;
    overflow: auto;
  }
}

.editor-container {
  .editor-header {
    padding: 16px 24px;
    border-bottom: 1px solid var(--el-border-color-lighter);
    display: flex;
    justify-content: space-between;
    align-items: flex-start;

    .script-info {
      flex: 1;
      margin-right: 16px;
      display: flex;
      flex-direction: column;
      gap: 8px;

      .info-row {
        display: flex;
        align-items: center;
        gap: 12px;

        .editable-tag {
          display: inline-block;
          cursor: pointer;

          .tag-input {
            width: 100px;
            margin: -4px 0; // 调整输入框位置以对齐标签
            .el-input__wrapper {
              padding: 0 8px;
              height: 24px;
              line-height: 24px;
            }
            .el-input__inner {
              height: 22px;
              line-height: 22px;
              font-size: 12px;
            }
          }

          &:hover .el-tag {
            border-color: var(--el-color-primary);
          }
        }

        .el-tag {
          transition: all 0.2s;
        }

        .description-input {
          width: 300px;

          &.no-border {
            .el-input__wrapper {
              box-shadow: none;
              background: transparent;

              &:hover {
                box-shadow: 0 0 0 1px var(--el-border-color) inset;
              }
            }
          }

          :deep(.el-input__wrapper) {
            .el-input__prefix {
              color: var(--el-text-color-secondary);
              margin-right: 4px;
            }

            .el-input__inner {
              color: var(--el-text-color-secondary);
              &::placeholder {
                color: var(--el-text-color-placeholder);
              }
            }
          }
        }

        .el-tag {
          &.el-tag--info {
            background-color: var(--el-color-info-light-9);
            border-color: var(--el-color-info-light-5);
            color: var(--el-color-info);
          }

          &.el-tag--success {
            background-color: var(--el-color-success-light-9);
            border-color: var(--el-color-success-light-5);
            color: var(--el-color-success);
          }
        }

        .update-time {
          font-size: 13px;
          color: var(--el-text-color-secondary);
        }
      }
    }

    .header-right {
      .language-select {
        width: 120px;
      }
    }
  }

  .editor-body {
    padding: 0 24px 24px;
    height: calc(80vh - 160px);
    overflow: auto;
  }
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 12px 24px;
  border-top: 1px solid var(--el-border-color-lighter);

  .el-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 8px 16px;
    line-height: 1;

    .el-icon {
      margin: 0;
    }
  }
}
</style>
